package com.ruowei.modules.foodOrder.web.rest;

import com.ruowei.common.error.exception.BadRequestAlertException;
import com.ruowei.common.error.exception.CommonException;
import com.ruowei.common.lang.StringUtils;
import com.ruowei.modules.foodOrder.domain.Merchandise;
import com.ruowei.modules.foodOrder.domain.MerchandiseSku;
import com.ruowei.modules.foodOrder.domain.ShoppingCart;
import com.ruowei.modules.foodOrder.domain.SkuOptionsRelationship;
import com.ruowei.modules.foodOrder.repository.*;
import com.ruowei.modules.foodOrder.service.OrderService;
import com.ruowei.modules.foodOrder.service.ShoppingCartService;
import com.ruowei.modules.foodOrder.web.dto.AddCartQM;
import com.ruowei.modules.foodOrder.web.dto.CartListDTO;
import com.ruowei.modules.foodOrder.web.dto.CartMerchandiseDTO;
import com.ruowei.modules.sys.utils.AppletTokenUtils;
import com.ruowei.modules.sys.utils.CommonUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * REST controller for managing {@link ShoppingCart}.
 */
@RestController
@RequestMapping("/api")
@Transactional
@Api(tags = "购物车相关接口")
public class ShoppingCartResource {

    private final Logger log = LoggerFactory.getLogger(ShoppingCartResource.class);

    private final ShoppingCartRepository shoppingCartRepository;
    private final MerchandiseSkuRepository merchandiseSkuRepository;
    private final MerchantRepository merchantRepository;
    private final MerchandiseRepository merchandiseRepository;
    private final SkuOptionsRelationshipRepository skuOptionsRelationshipRepository;
    private final AttributeOptionsRepository attributeOptionsRepository;
    private final ShoppingCartService shoppingCartService;
    private final OrderService orderService;

    public ShoppingCartResource(ShoppingCartRepository shoppingCartRepository, MerchandiseSkuRepository merchandiseSkuRepository, MerchantRepository merchantRepository, MerchandiseRepository merchandiseRepository, SkuOptionsRelationshipRepository skuOptionsRelationshipRepository, AttributeOptionsRepository attributeOptionsRepository, ShoppingCartService shoppingCartService, OrderService orderService) {
        this.shoppingCartRepository = shoppingCartRepository;
        this.merchandiseSkuRepository = merchandiseSkuRepository;
        this.merchantRepository = merchantRepository;
        this.merchandiseRepository = merchandiseRepository;
        this.skuOptionsRelationshipRepository = skuOptionsRelationshipRepository;
        this.attributeOptionsRepository = attributeOptionsRepository;
        this.shoppingCartService = shoppingCartService;
        this.orderService = orderService;
    }

    @PostMapping("/applet/shoppingCart/add")
    @ApiOperation(value = "添加购物车")
    public ResponseEntity<String> addShoppingCart(HttpServletRequest request, @RequestBody AddCartQM qm) {
        String cartCode;
        String memberCode = AppletTokenUtils.getOpenIdByToken(request).getOpenId();
        Optional<Merchandise> merchandiseOptional = merchandiseRepository.findOneByMerchandiseCodeAndDeleteStatus(qm.getMerchandiseCode(), false);

        if (merchandiseOptional.isPresent()) {
            Merchandise merchandise = merchandiseOptional.get();
            if (!merchandise.isPublishStatus()) {
                throw new BadRequestAlertException("该商品已下架，请重新选购");
            }
        }

        Optional<ShoppingCart> shoppCart = shoppingCartRepository.findBySkuCodeAndMerchandiseCodeAndMerchantCodeAndMemberCode(qm.getSkuCode(), qm.getMerchandiseCode(), qm.getMerchantCode(), memberCode);

        //传购物车编码
        if (StringUtils.isNotEmpty(qm.getCartCode())) {
            Optional<ShoppingCart> aCart = shoppingCartRepository.findByCartCode(qm.getCartCode());
            if (!aCart.isPresent()) {
                throw new BadRequestAlertException("购物车已被处理，请重新选购");
            }
            ShoppingCart shoppingCart = aCart.get();
            cartCode = shoppingCart.getCartCode();
            addQuantity(shoppingCart, qm.getNumber(), memberCode);
        } else if (shoppCart.isPresent()) {
            ShoppingCart sc = shoppCart.get();
            cartCode = sc.getCartCode();
            addQuantity(sc, qm.getNumber(), memberCode);
        } else {
            //不传购物车编码
            ShoppingCart cart = new ShoppingCart();
            cartCode = CommonUtils.getUUID();
            cart.setCartCode(cartCode);
            cart.setMemberCode(memberCode);
            cart.setMerchandiseCode(qm.getMerchandiseCode());
            if (!merchandiseOptional.isPresent()) {
                throw new CommonException("该商品无效，请重新选购");
            }
            cart.setMerchandiseName(merchandiseOptional.get().getMerchandiseName());
            cart.setMerchantCode(qm.getMerchantCode());
            cart.setSkuCode(qm.getSkuCode());
            cart.setMerchandiseQuantity(qm.getNumber());
            Optional<MerchandiseSku> sku = merchandiseSkuRepository.findBySkuCodeAndStatus(qm.getSkuCode(), true);
            if (!sku.isPresent()) {
                throw new BadRequestAlertException("商品规格发生变化，请重新选购");
            }
            MerchandiseSku merchandiseSku = sku.get();
            int num = merchandiseSku.getAddedTimes() + qm.getNumber();
            merchandiseSku.setAddedTimes(num);
            shoppingCartRepository.save(cart);
            merchandiseSkuRepository.save(merchandiseSku);
        }
        return ResponseEntity.ok(cartCode);
    }

    private void addQuantity(ShoppingCart shoppingCart, Integer quantity, String memberCode) {
        Optional<Merchandise> merchandiseOptional2 = merchandiseRepository.findOneByMerchandiseCodeAndDeleteStatus(shoppingCart.getMerchandiseCode(), false);
        if (!merchandiseOptional2.isPresent()) {
            throw new CommonException("该商品无效，请重新选购");
        }
        Merchandise merchandise2 = merchandiseOptional2.get();
        if (!merchandise2.isPublishStatus()) {
            throw new BadRequestAlertException("该商品已下架，请重新选购");
        }
        int num = shoppingCart.getMerchandiseQuantity() + quantity;
        shoppingCart.setMerchandiseQuantity(num);
        shoppingCartRepository.save(shoppingCart);
        Optional<MerchandiseSku> sku = merchandiseSkuRepository.findBySkuCodeAndStatus(shoppingCart.getSkuCode(), true);
        if (!sku.isPresent()) {
            shoppingCartRepository.deleteBySkuCodeAndMemberCode(shoppingCart.getSkuCode(), memberCode);
            throw new BadRequestAlertException("商品规格发生变化，请重新选购");
        }
        MerchandiseSku merchandiseSku = sku.get();
        int number = merchandiseSku.getAddedTimes() + quantity;
        merchandiseSku.setAddedTimes(number);
        merchandiseSkuRepository.save(merchandiseSku);
    }

    @GetMapping("/applet/shoppingCart/getList")
    @ApiOperation(value = "获取购物车列表")
    public ResponseEntity<List<CartListDTO>> getList(HttpServletRequest request, @RequestParam(required = false) String merchantCode) {
        List<CartListDTO> cartList = new ArrayList<>();
        //传商家编码
        if (StringUtils.isNotEmpty(merchantCode)) {
            //用于存商家，商品列表信息
            CartListDTO listDTO = new CartListDTO();
            //获取商家信息
            merchantRepository.findByMerchantCode(merchantCode)
                .ifPresent(merchant -> {
                    listDTO.setMerchantCode(merchant.getMerchantCode());
                    listDTO.setMerchantName(merchant.getMerchantName());
                    listDTO.setStartingPrice(merchant.getStartingPrice());
                });
            //商品列表信息
            List<CartMerchandiseDTO> merchandiseList = new ArrayList<>();
            //查某个用户在某个商家所有的购物车数据
            List<ShoppingCart> carts = shoppingCartRepository.findAllByMemberCodeAndMerchantCode(AppletTokenUtils.getOpenIdByToken(request).getOpenId(), merchantCode);
            carts.forEach(shoppingCart -> {
                getMerchandiseFromCart(merchandiseList, shoppingCart);
            });
            listDTO.setMerchandiseList(merchandiseList);
            cartList.add(listDTO);
        } else {
            //没有传商家编码，查询用户全部购物车，购物车根据商家编码分组去重
            shoppingCartRepository.findGroupByMerchantCode(AppletTokenUtils.getOpenIdByToken(request).getOpenId())
                .forEach(cart -> {
                    //用于存商家，商品列表信息
                    CartListDTO list = new CartListDTO();
                    //存商家信息
                    merchantRepository.findByMerchantCode(cart.getMerchantCode())
                        .ifPresent(merchant -> {
                            list.setMerchantCode(merchant.getMerchantCode());
                            list.setMerchantName(merchant.getMerchantName());
                            list.setStartingPrice(merchant.getStartingPrice());
                        });
                    //用于存商家下的所有商品信息
                    List<CartMerchandiseDTO> merchandiseList = new ArrayList<>();
                    //获取某个商家下的所有商品信息
                    shoppingCartRepository.findAllByMemberCodeAndMerchantCode(AppletTokenUtils.getOpenIdByToken(request).getOpenId(), cart.getMerchantCode())
                        .forEach(shoppCart -> {
                            getMerchandiseFromCart(merchandiseList, shoppCart);
                        });
                    list.setMerchandiseList(merchandiseList);
                    cartList.add(list);
                });
        }
        return ResponseEntity.ok(cartList);
    }

    private void getMerchandiseFromCart(List<CartMerchandiseDTO> merchandiseList, ShoppingCart shoppCart) {
        CartMerchandiseDTO merchandiseDTO = new CartMerchandiseDTO();
        //存购物车编码，商品数量
        merchandiseDTO.setCartCode(shoppCart.getCartCode());
        merchandiseDTO.setQuantity(shoppCart.getMerchandiseQuantity());
        merchandiseRepository.findOneByMerchandiseCodeAndDeleteStatus(shoppCart.getMerchandiseCode(), false)
            .ifPresent(merchandise -> {
                //商品名，图片，编码
                merchandiseDTO.setCode(merchandise.getMerchandiseCode());
                merchandiseDTO.setName(merchandise.getMerchandiseName());
                merchandiseDTO.setPhoto(merchandise.getPhotos());
            });
        Optional<MerchandiseSku> skuOptional = merchandiseSkuRepository.findFirstBySkuCode(shoppCart.getSkuCode());
        if (skuOptional.isPresent()) {
            MerchandiseSku sku = skuOptional.get();
            //单价，包装费
            merchandiseDTO.setPrice(sku.getUnitPrice());
            merchandiseDTO.setPackingFee(sku.getPackingFee());
            //sku描述
            StringBuilder builder = new StringBuilder();
            List<SkuOptionsRelationship> list = skuOptionsRelationshipRepository.findAllBySkuCode(shoppCart.getSkuCode());
            if (list.size() == 0) {
                merchandiseDTO.setSku(null);
            } else {
                list.forEach(skuOptionsRelationship -> {
                    attributeOptionsRepository.findByOptionCode(skuOptionsRelationship.getOptionCode())
                        .ifPresent(attributeOptions -> {
                            builder.append(attributeOptions.getOptionName()).append("/");
                        });
                });
                if (builder.length() > 0) {
                    builder.deleteCharAt(builder.length() - 1);
                }
                merchandiseDTO.setSku(builder.toString());
            }
            merchandiseList.add(merchandiseDTO);
        }
        shoppCart.setMerchandiseName(merchandiseDTO.getName());
        shoppingCartRepository.saveAndFlush(shoppCart);
    }

    @PostMapping("/applet/shoppingCart/delete")
    @ApiOperation(value = "减少/删除购物车")
    public ResponseEntity<String> delete(@RequestParam String cartCode) {
        shoppingCartRepository.findByCartCode(cartCode)
            .ifPresent(shoppingCart -> {
                if (shoppingCart.getMerchandiseQuantity() == 1) {
                    shoppingCartRepository.delete(shoppingCart);
                } else {
                    int num = shoppingCart.getMerchandiseQuantity() - 1;
                    shoppingCart.setMerchandiseQuantity(num);
                    shoppingCartRepository.save(shoppingCart);
                }
            });
        return ResponseEntity.ok().build();
    }

    @PostMapping("/applet/shoppingCart/clear")
    @ApiOperation(value = "清空购物车")
    public ResponseEntity<String> clear(HttpServletRequest request, @RequestParam(required = false) String merchantCode) {
        shoppingCartService.clearShoppingCart(merchantCode, request);
        return ResponseEntity.ok().build();
    }
}
